package com.jetbrains.qodana.sarif.model;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.time.Instant;
import java.util.Set;


/**
 * Contains information about how and when a result was detected.
 */
@SuppressWarnings("DuplicatedCode")
public class ResultProvenance implements PropertyOwner {

    /**
     * The Coordinated Universal Time (UTC) date and time at which the result was first detected. See "Date/time properties" in the SARIF spec for the required format.
     */
    @SerializedName("firstDetectionTimeUtc")
    @Expose
    private Instant firstDetectionTimeUtc;
    /**
     * The Coordinated Universal Time (UTC) date and time at which the result was most recently detected. See "Date/time properties" in the SARIF spec for the required format.
     */
    @SerializedName("lastDetectionTimeUtc")
    @Expose
    private Instant lastDetectionTimeUtc;
    /**
     * A GUID-valued string equal to the automationDetails.guid property of the run in which the result was first detected.
     */
    @SerializedName("firstDetectionRunGuid")
    @Expose
    private String firstDetectionRunGuid;
    /**
     * A GUID-valued string equal to the automationDetails.guid property of the run in which the result was most recently detected.
     */
    @SerializedName("lastDetectionRunGuid")
    @Expose
    private String lastDetectionRunGuid;
    /**
     * The index within the run.invocations array of the invocation object which describes the tool invocation that detected the result.
     */
    @SerializedName("invocationIndex")
    @Expose
    private Integer invocationIndex = null;
    /**
     * An array of physicalLocation objects which specify the portions of an analysis tool's output that a converter transformed into the result.
     */
    @SerializedName("conversionSources")
    @Expose
    private Set<PhysicalLocation> conversionSources = null;
    /**
     * Key/value pairs that provide additional information about the object.
     */
    @SerializedName("properties")
    @Expose
    private PropertyBag properties;

    /**
     * The Coordinated Universal Time (UTC) date and time at which the result was first detected. See "Date/time properties" in the SARIF spec for the required format.
     */
    public Instant getFirstDetectionTimeUtc() {
        return firstDetectionTimeUtc;
    }

    /**
     * The Coordinated Universal Time (UTC) date and time at which the result was first detected. See "Date/time properties" in the SARIF spec for the required format.
     */
    public void setFirstDetectionTimeUtc(Instant firstDetectionTimeUtc) {
        this.firstDetectionTimeUtc = firstDetectionTimeUtc;
    }

    public ResultProvenance withFirstDetectionTimeUtc(Instant firstDetectionTimeUtc) {
        this.firstDetectionTimeUtc = firstDetectionTimeUtc;
        return this;
    }

    /**
     * The Coordinated Universal Time (UTC) date and time at which the result was most recently detected. See "Date/time properties" in the SARIF spec for the required format.
     */
    public Instant getLastDetectionTimeUtc() {
        return lastDetectionTimeUtc;
    }

    /**
     * The Coordinated Universal Time (UTC) date and time at which the result was most recently detected. See "Date/time properties" in the SARIF spec for the required format.
     */
    public void setLastDetectionTimeUtc(Instant lastDetectionTimeUtc) {
        this.lastDetectionTimeUtc = lastDetectionTimeUtc;
    }

    public ResultProvenance withLastDetectionTimeUtc(Instant lastDetectionTimeUtc) {
        this.lastDetectionTimeUtc = lastDetectionTimeUtc;
        return this;
    }

    /**
     * A GUID-valued string equal to the automationDetails.guid property of the run in which the result was first detected.
     */
    public String getFirstDetectionRunGuid() {
        return firstDetectionRunGuid;
    }

    /**
     * A GUID-valued string equal to the automationDetails.guid property of the run in which the result was first detected.
     */
    public void setFirstDetectionRunGuid(String firstDetectionRunGuid) {
        this.firstDetectionRunGuid = firstDetectionRunGuid;
    }

    public ResultProvenance withFirstDetectionRunGuid(String firstDetectionRunGuid) {
        this.firstDetectionRunGuid = firstDetectionRunGuid;
        return this;
    }

    /**
     * A GUID-valued string equal to the automationDetails.guid property of the run in which the result was most recently detected.
     */
    public String getLastDetectionRunGuid() {
        return lastDetectionRunGuid;
    }

    /**
     * A GUID-valued string equal to the automationDetails.guid property of the run in which the result was most recently detected.
     */
    public void setLastDetectionRunGuid(String lastDetectionRunGuid) {
        this.lastDetectionRunGuid = lastDetectionRunGuid;
    }

    public ResultProvenance withLastDetectionRunGuid(String lastDetectionRunGuid) {
        this.lastDetectionRunGuid = lastDetectionRunGuid;
        return this;
    }

    /**
     * The index within the run.invocations array of the invocation object which describes the tool invocation that detected the result.
     */
    public Integer getInvocationIndex() {
        return invocationIndex;
    }

    /**
     * The index within the run.invocations array of the invocation object which describes the tool invocation that detected the result.
     */
    public void setInvocationIndex(Integer invocationIndex) {
        this.invocationIndex = invocationIndex;
    }

    public ResultProvenance withInvocationIndex(Integer invocationIndex) {
        this.invocationIndex = invocationIndex;
        return this;
    }

    /**
     * An array of physicalLocation objects which specify the portions of an analysis tool's output that a converter transformed into the result.
     */
    public Set<PhysicalLocation> getConversionSources() {
        return conversionSources;
    }

    /**
     * An array of physicalLocation objects which specify the portions of an analysis tool's output that a converter transformed into the result.
     */
    public void setConversionSources(Set<PhysicalLocation> conversionSources) {
        this.conversionSources = conversionSources;
    }

    public ResultProvenance withConversionSources(Set<PhysicalLocation> conversionSources) {
        this.conversionSources = conversionSources;
        return this;
    }

    /**
     * Key/value pairs that provide additional information about the object.
     */
    @Override
    public PropertyBag getProperties() {
        return properties;
    }

    /**
     * Key/value pairs that provide additional information about the object.
     */
    @Override
    public void setProperties(PropertyBag properties) {
        this.properties = properties;
    }

    public ResultProvenance withProperties(PropertyBag properties) {
        this.properties = properties;
        return this;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(ResultProvenance.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
        sb.append("firstDetectionTimeUtc");
        sb.append('=');
        sb.append(((this.firstDetectionTimeUtc == null) ? "<null>" : this.firstDetectionTimeUtc));
        sb.append(',');
        sb.append("lastDetectionTimeUtc");
        sb.append('=');
        sb.append(((this.lastDetectionTimeUtc == null) ? "<null>" : this.lastDetectionTimeUtc));
        sb.append(',');
        sb.append("firstDetectionRunGuid");
        sb.append('=');
        sb.append(((this.firstDetectionRunGuid == null) ? "<null>" : this.firstDetectionRunGuid));
        sb.append(',');
        sb.append("lastDetectionRunGuid");
        sb.append('=');
        sb.append(((this.lastDetectionRunGuid == null) ? "<null>" : this.lastDetectionRunGuid));
        sb.append(',');
        sb.append("invocationIndex");
        sb.append('=');
        sb.append(((this.invocationIndex == null) ? "<null>" : this.invocationIndex));
        sb.append(',');
        sb.append("conversionSources");
        sb.append('=');
        sb.append(((this.conversionSources == null) ? "<null>" : this.conversionSources));
        sb.append(',');
        sb.append("properties");
        sb.append('=');
        sb.append(((this.properties == null) ? "<null>" : this.properties));
        sb.append(',');
        if (sb.charAt((sb.length() - 1)) == ',') {
            sb.setCharAt((sb.length() - 1), ']');
        } else {
            sb.append(']');
        }
        return sb.toString();
    }

    @Override
    public int hashCode() {
        int result = 1;
        result = ((result * 31) + ((this.firstDetectionRunGuid == null) ? 0 : this.firstDetectionRunGuid.hashCode()));
        result = ((result * 31) + ((this.lastDetectionTimeUtc == null) ? 0 : this.lastDetectionTimeUtc.hashCode()));
        result = ((result * 31) + ((this.invocationIndex == null) ? 0 : this.invocationIndex.hashCode()));
        result = ((result * 31) + ((this.lastDetectionRunGuid == null) ? 0 : this.lastDetectionRunGuid.hashCode()));
        result = ((result * 31) + ((this.conversionSources == null) ? 0 : this.conversionSources.hashCode()));
        result = ((result * 31) + ((this.firstDetectionTimeUtc == null) ? 0 : this.firstDetectionTimeUtc.hashCode()));
        result = ((result * 31) + ((this.properties == null) ? 0 : this.properties.hashCode()));
        return result;
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if (!(other instanceof ResultProvenance)) {
            return false;
        }
        ResultProvenance rhs = ((ResultProvenance) other);
        //noinspection ConstantValue,EqualsReplaceableByObjectsCall,StringEquality,NumberEquality
        return ((((((((this.firstDetectionRunGuid == rhs.firstDetectionRunGuid) || ((this.firstDetectionRunGuid != null) && this.firstDetectionRunGuid.equals(rhs.firstDetectionRunGuid))) && ((this.lastDetectionTimeUtc == rhs.lastDetectionTimeUtc) || ((this.lastDetectionTimeUtc != null) && this.lastDetectionTimeUtc.equals(rhs.lastDetectionTimeUtc)))) && ((this.invocationIndex == rhs.invocationIndex) || ((this.invocationIndex != null) && this.invocationIndex.equals(rhs.invocationIndex)))) && ((this.lastDetectionRunGuid == rhs.lastDetectionRunGuid) || ((this.lastDetectionRunGuid != null) && this.lastDetectionRunGuid.equals(rhs.lastDetectionRunGuid)))) && ((this.conversionSources == rhs.conversionSources) || ((this.conversionSources != null) && this.conversionSources.equals(rhs.conversionSources)))) && ((this.firstDetectionTimeUtc == rhs.firstDetectionTimeUtc) || ((this.firstDetectionTimeUtc != null) && this.firstDetectionTimeUtc.equals(rhs.firstDetectionTimeUtc)))) && ((this.properties == rhs.properties) || ((this.properties != null) && this.properties.equals(rhs.properties))));
    }

}
